package touchtouch;

import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Polygon;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Vector;

import javax.swing.JPanel;
import javax.swing.Timer;

import touchtouch.geometry.GrahamScanConvexHull;
import touchtouch.geometry.newPoint;
import wiiusej.Wiimote;
import wiiusej.values.IRSource;
import wiiusej.wiiusejevents.physicalevents.ExpansionEvent;
import wiiusej.wiiusejevents.physicalevents.IREvent;
import wiiusej.wiiusejevents.physicalevents.MotionSensingEvent;
import wiiusej.wiiusejevents.physicalevents.WiimoteButtonsEvent;
import wiiusej.wiiusejevents.utils.WiimoteListener;
import wiiusej.wiiusejevents.wiiuseapievents.ClassicControllerInsertedEvent;
import wiiusej.wiiusejevents.wiiuseapievents.ClassicControllerRemovedEvent;
import wiiusej.wiiusejevents.wiiuseapievents.DisconnectionEvent;
import wiiusej.wiiusejevents.wiiuseapievents.GuitarHeroInsertedEvent;
import wiiusej.wiiusejevents.wiiuseapievents.GuitarHeroRemovedEvent;
import wiiusej.wiiusejevents.wiiuseapievents.NunchukInsertedEvent;
import wiiusej.wiiusejevents.wiiuseapievents.NunchukRemovedEvent;
import wiiusej.wiiusejevents.wiiuseapievents.StatusEvent;

public class CornersListener implements WiimoteListener, ActionListener{

	public final static int NW_CORNER	= 0;
	public final static int NE_CORNER	= 1;
	public final static int SW_CORNER	= 2;
	public final static int SE_CORNER	= 3;

	Point[] corners = new Point[4];
	public boolean is_tracking_finish = false;
	static public boolean is_event_processed = false;
	public int corner_to_track = NW_CORNER;
	JPanel panel;
	Wiimote wiimote;

	int freq = 100; //frequence théorique
	int delay = new Double(1000 / freq).intValue(); //delais théorique entre deux événements (en ms)
	int eff_delay = new Double(delay * 1.666).intValue(); //delais effectif supposé entre deux événements (en ms)

	IREvent last_event;
	boolean event_occured = false; //détection d'un événement ou de l'absence d'un évenement

	long last_event_begin_at; // date du début de l'evt
	long last_event_end_at; // période depuis le début de l'evt
	long no_event_begin_at; // date du début de l'asence d'evt
	long no_event_end_at; // période depuis le début de l'absence d'evt

	Timer timer; // traite l'absence d'evt

	public CornersListener(JPanel panel, Wiimote wiimote){
		this.panel = panel;
		this.wiimote = wiimote;
		no_event_begin_at = System.currentTimeMillis();
		timer = new Timer (eff_delay, this);
		timer.start();
	}

	// PointList polygone;
	Vector<newPoint> raw_polygon = new Vector<newPoint>(100, 100);

	int[] last_point = null;
	boolean[] evts = new boolean[]{false, false, false, false};

	public void actionPerformed (ActionEvent event){

		// si pas de marque d'evt
		if (!event_occured){
			System.out.println("no");
			if(last_point != null){
				drawShape();
				raw_polygon.clear();
			}
			last_point = null;
		}

		// si une marque de présence d'evt
		if (event_occured){
			// enlever la marque
			event_occured=false;
			// le traiter
			{
				System.out.println("yes" );
				IRSource[] points = last_event.getIRPoints();
				//IRSource p = points[0];
				//short s = p.getSize();
				//((Graphics2D)panel.getGraphics()).getStroke().
				if (last_point!=null)
					((Graphics2D)panel.getGraphics()).drawLine(
							1024 - last_event.getAx(),
							768 - last_event.getAy(),
							last_point[0],
							last_point[1]);
				else{
					raw_polygon.add( new newPoint(1024 - last_event.getAx(), 768 - last_event.getAy()) );
				}
				last_point = new int[]{1024 - last_event.getAx(), 768 - last_event.getAy()};
				raw_polygon .add( new newPoint(1024 - last_event.getAx(), 768 - last_event.getAy()) );
			}
		}
	}

	public void drawShape(){
		System.out.println("shape");
			// construction du polygone (awt)
			Vector<newPoint> convexHull = new GrahamScanConvexHull().doGraham(raw_polygon);
			Polygon convexHullShape = new Polygon();
			//polygone = Convexe.zyva(polygone); // non pourri

			if (convexHull!=null){
			for(int i = 0 ; i < convexHull.size() ; i++ ){
				newPoint p = convexHull.elementAt(i);
				convexHullShape.addPoint(p.x, p.y);
			}

			// affichage
			Graphics2D g = (Graphics2D) panel.getGraphics();
			Color c = new Color(
					new Double(Math.round(Math.random()*100)+120).intValue(),
					new Double(Math.round(Math.random()*100)+120).intValue(),
					new Double(Math.round(Math.random()*100)+120).intValue());
			g.setColor(c);
			g.fill(convexHullShape);
		}
	}
	synchronized public void onIrEvent(IREvent e) {
		event_occured = true;
		last_event = e;
		/*if(!is_event_processed){
			wiimote.removeWiiMoteEventListeners(this);
			is_event_processed = true;
			// arreter l'IR tracking
		wiimote.deactivateIRTRacking();
			// vider le buffer d'evenement
				//???

			// traiter l'evt
			corners[corner_to_track] = new Point(e.getX(), e.getY());
			System.out.println("corner n°" + corner_to_track + " --> x:" + e.getX() + " \ty:" + e.getY());
			corner_to_track++;
			if(corner_to_track == 4){
				is_tracking_finish = true;
				//wiimote.removeWiiMoteEventListeners(this);
			}

			//attendre un peu
			try {
				Thread.sleep(2000);
			} catch (InterruptedException e1) {e1.printStackTrace();}

			is_event_processed = false;

			if(corner_to_track < 4)
				wiimote.addWiiMoteEventListeners(this);
			// reprendre l'IR tracking
		wiimote.activateIRTRacking();
		System.out.println();
		}*/
		// System.out.println("corner n°" + corner_to_track++ + " --> x:" + e.getAx() + " \ty:" + e.getAy());
	}

	public void onButtonsEvent(WiimoteButtonsEvent arg0) {}

	public void onClassicControllerInsertedEvent(ClassicControllerInsertedEvent arg0) {}

	public void onClassicControllerRemovedEvent(ClassicControllerRemovedEvent arg0) {}

	public void onDisconnectionEvent(DisconnectionEvent arg0) {}

	public void onExpansionEvent(ExpansionEvent arg0) {}

	public void onGuitarHeroInsertedEvent(GuitarHeroInsertedEvent arg0) {}

	public void onGuitarHeroRemovedEvent(GuitarHeroRemovedEvent arg0) {}

	public void onMotionSensingEvent(MotionSensingEvent arg0) {}

	public void onNunchukInsertedEvent(NunchukInsertedEvent arg0) {}

	public void onNunchukRemovedEvent(NunchukRemovedEvent arg0) {}

	public void onStatusEvent(StatusEvent arg0) {}

}
